/*
This search routine is based on the free Recon Search Engine
by Jerry Bradenbaugh (http://www.serve.com/hotsyte/)
alterations have been made by Marc Reed (http://www.marcreed.com)
This script may be used for free
*/

// Define global variables

// the maxPages variable determines how
// many results are displayed per page:
var maxPages = 10;

//global array profiles - created by the Sitesearch.exe file and stored in searchIndex.js

//global array of the results of the search. One match per dimensions. Each element contains the no. of times match occurs, page title, brief desc, remaining content, and poss. file path and name, all separated by "|"
var MatchedResults = new Array(); 
var SearchText = "";	//global array containing the filtered text to be searched for

var Currentmatch = new Array();
var indexer = 0;
var srcCrit = "any"
var count = 0;
var start = 0;
var DetailsWindow; //window opened with the full content for a page written to it, with search text highlighted
var newContent = "";

//Create list of lecture details (no., title and lecturer) so can search against title, and match, 
//and have access to other info required for opening lecture window.
//Each main dimension is a lecture, the secondary dim has fields for lecture title, lecture number prefix, lecturer file
var maxLectures = 11;
var Lectures = new Array();
Lectures [0] = new Array();
Lectures [0] [0] = "Mathematics Preliminary";
Lectures [0] [1] = "Session 1: ";
Lectures [0] [2] = "Dan_Jackson.htm";

Lectures [1] = new Array();
Lectures [1] [0] = "Basic Probability Concepts";
Lectures [1] [1] = "Session 2: ";
Lectures [1] [2] = "Ian_Mchale.htm";

Lectures [2] = new Array();
Lectures [2] [0] = "Continuous Lifetime Distributions 1";
Lectures [2] [1] = "Session 3: ";
Lectures [2] [2] = "Andrew_Brint.htm";

Lectures [3] = new Array();
Lectures [3] [0] = "Continuous Lifetime Distributions 2";
Lectures [3] [1] = "Session 4: ";
Lectures [3] [2] = "Andrew_Brint.htm";

Lectures [4] = new Array();
Lectures [4] [0] = "Model Selection";
Lectures [4] [1] = "Session 5: ";
Lectures [4] [2] = "Rose_Baker.htm";

Lectures [5] = new Array();
Lectures [5] [0] = "Model Fitting";
Lectures [5] [1] = "Session 6: ";
Lectures [5] [2] = "Ian_Mchale.htm";

Lectures [6] = new Array();
Lectures [6] [0] = "Testing Model Fitness";
Lectures [6] [1] = "Session 7: ";
Lectures [6] [2] = "Ian_Mchale.htm";

Lectures [7] = new Array();
Lectures [7] [0] = "Regression Modelling";
Lectures [7] [1] = "Session 8: ";
Lectures [7] [2] = "Ian_Mchale.htm";

Lectures [8] = new Array();
Lectures [8] [0] = "Proportional Hazards and Accelerated Life Models";
Lectures [8] [1] = "Session 9: ";
Lectures [8] [2] = "Wenbin_Wang.htm";

Lectures [9] = new Array();
Lectures [9] [0] = "Repairable Systems";
Lectures [9] [1] = "Session 10: ";
Lectures [9] [2] = "Wenbin_Wang.htm";

Lectures [10] = new Array();
Lectures [10] [0] = "Renewal Processes";
Lectures [10] [1] = "Session 11: ";
Lectures [10] [2] = "Rose_Baker.htm";

Lectures [11] = new Array();
Lectures [11] [0] = "The Bayesian Approach";
Lectures [11] [1] = "Session 12: ";
Lectures [11] [2] = "David_Percy.htm";

//Search Results page should call this function
function doSearch() {
	fullEntry = getQueryString('searchField');
	//Look for ++(clean up multiple spaces)
	var PlusSigns = "\+\+"
	while (fullEntry.indexOf(PlusSigns) >= 0) {
		fullEntry=fullEntry.replace(/\+\+/, "+")
	}
	
	//Isolate search term(s) and convert "+" to spaces
	for (i=0; i<fullEntry.length; i++) {
		if ((fullEntry.charAt(i) == "&")||(fullEntry.charAt(i) == "#")) {
			break
		}
		if (fullEntry.charAt(i) == "+") {
			SearchText = (SearchText+" ")
		}else {
			SearchText = (SearchText+(fullEntry.charAt(i)))
		}
	}
	if (SearchText.indexOf("#") > -1) SearchText = SearchText.substring(0, SearchText.indexOf("#"));
	validate(SearchText);
}

//This generic function will return the value of a QueryString
function getQueryString(Val) {
//splits the search string into its parameters, then splits a parameter (determined by Val) into its name and value 
//components. Returns the value.

	thisURLparamStr = parent.document.location.search;
	//chop "?" off thisURLparamStr
	if (thisURLparamStr.charAt(0) == "?") thisURLparamStr = thisURLparamStr.substring(1, thisURLparamStr.length);
	returnStr = "";
	if (thisURLparamStr != "") {
		//Build array out of thisURLparamStr using "&" as delimiter
		divide1=(thisURLparamStr.split("&"))
		for (i=0; i < divide1.length; i++) {
			divide2 = divide1[i].split("=")
			if (unescape(divide2[0]) == Val) {
				returnStr = unescape(divide2[1]);
			}
		}
	}
	return returnStr;
}

//Determine any word/all words/phrase search
function validate(text) {
	
	//clean up spaces at beginning of string
	while (text.charAt(0) == ' ') {					
		text = text.substring(1,text.length);
	}
	//clean up spaces at end of string
	while (text.charAt(text.length - 1) == ' ') {
		text = text.substring(0,text.length - 1);
	} 

	var entry = text;
	
	if ((entry.charAt(0) == "+")||(getQueryString('srcriteria') == "all")) {
		entry = (entry.charAt(0) == "+")? entry.substring(1,entry.length):entry;
		srcCrit = "all"
	}
	//If user wants exact phrase
	if (((entry.charAt(0) == "\"")&&(entry.charAt((entry.length)-1) == "\""))||(getQueryString('srcriteria') == "phrase")){
		while (entry.indexOf("\"") > -1) {
			entry=entry.replace(/\"/, "")
		}
		srcCrit = "phrase"
	}
	if (entry.length < 2) {
		alert("Please type a word of at least two characters.");
		return;
	}
	convertString(entry, text);
}


// If not exact phrase, split the entry string into an array
function convertString(reentry, text) {
	//If user wants exact phrase
	if (srcCrit == "phrase") {
		searchTerm = reentry;
		requirePhrase(searchTerm, text);
		return;
	}
	searchArray = reentry.split(" ");
	if (srcCrit == "any") { allowAny(searchArray, text); return; }
	if (srcCrit == "all") { requireAll(searchArray, text); return; }
}


//*************************************************************
// This function merges brief description, page content,
// keywords and returns all-caps string
//*************************************************************
function mergeCaps(str2, str3) {
	mergeStr = "";
	// join str2 (brief description) and str3 (rest of page text)
	// if page content is longer than brief description length,
	// then str2 ends "..."
	// if str2 ends "..." remove dots
	if ((str2.length > 0) && (str2.charAt(0) != " ")) str2 = " " + str2;
	if (str2.substring(str2.length - 3, str2.length) == "...") {
			mergeString = str2.substring(0, str2.length - 3).concat(str3);
	} else {
			mergeString = str2.concat(str3);
	}
	//to make search case-insensitive, convert to all caps
	return mergeString.toUpperCase();

}

//*************************************************************************
// This function will parse the URL search string and change a name/value pair
//*************************************************************************
function changeParam(whichParam, newVal) {
	newParamStr = "";
	thisURLstr = parent.document.location.href.substring(0, parent.document.location.href.indexOf("?"));
	thisURLparamStr = parent.document.location.href.substring(parent.document.location.href.indexOf("?") + 1, parent.document.location.href.length);
	//Build array out of thisURLparamStr using "&" as delimiter
	divide1=(thisURLparamStr.split("&"))
	for (cnt=0; cnt < divide1.length; cnt++) {
		divide2 = divide1[cnt].split("=")
		if (divide2[0] == whichParam) {
			// if we find whichParam in thisURLparamStr replace whichParam's value with newVal
			newParamStr = newParamStr + divide2[0] + "=" + escape(newVal) + "&";
		} else {
			//leave other parameters intact
			newParamStr = newParamStr + divide2[0] + "=" + divide2[1] + "&";
		}
	}
	//strip off trailing ampersand
	if (newParamStr.charAt(newParamStr.length - 1) == "&") newParamStr = newParamStr.substring(0, newParamStr.length - 1);
	//apply new URL
 	return(thisURLstr + "?" + newParamStr);
}


//*************************************************************
// Sorts search results based on 1.Number of hits 2.aplhabetically
//*************************************************************
function compare(a, b) {
	if (parseInt(a) - parseInt(b) != 0) {
		return parseInt(a) - parseInt(b)
	}else {
		var aComp = a.substring(a.indexOf("|") + 1, a.length)
		var bComp = b.substring(b.indexOf("|") + 1, b.length)
		if (aComp < bComp) {return -1}
		if (aComp > bComp) {return 1}
		return 0
	}
}


//Evoked if user searches ANY WORDS
function allowAny(t, text) {
//profiles is an array of all pages in the module, containing the module title, brief desc (inc H1), rest of page content, and file path and name all separated by "|"
//t is an array of words to search for
	var OccurNum = 0;

	for (i = 0; i < profiles.length; i++) {
		//strip url out of search string
		var refineElement = "";
		var splitline = profiles[i].split("|");
		//refineElement: capitalised content for current page which is searched 
		refineElement = mergeCaps(splitline[1], splitline[2]);
		OccurNum = 0;
		
		for (j = 0; j < t.length; j++) {
			
			eval("myRE = /" + t[j] + "/gi");
			OccurArray = refineElement.match(myRE);
			if (OccurArray != null) OccurNum = OccurNum + OccurArray.length;
			
		}
		if (OccurNum > 0) {
			//Store results in MatchedResults, adding number of occurances on page, and splitting title out of brief description in Profiles
			TitleSep = splitline[1].indexOf("¤");	//Sep is actually "¤ "
			MatchedResults[indexer] = (0-OccurNum) + "|" + splitline[0] + "|" + splitline[1].substring(0, TitleSep) + "|" + splitline[1].substring(TitleSep+2) + "|" + splitline[2] + "|" + splitline[3];
			indexer++;
		}
	}

	if (MatchedResults.length == 0) {						// If no matches are found, print a no match
		setTimeout("noMatch('"+text+"')",20); 	//write banner text. setTimeout only takes a literal string as the call to the function
		return;
	}
	else { 
		SearchText = text;
		SortResults();
		formatResults(1); 
	}					// Otherwise, generate a results document
}

//Evoked if user searches ALL WORDS
function requireAll(t, text) {
	var OccurNum = 0;
	for (i = 0; i < profiles.length; i++) {
		var allConfirmation = true;
		var refineAllString = "";
		var splitline = profiles[i].split("|");
		//refineAllString: capitalised content for current page which gets searched
		refineAllString = mergeCaps(splitline[1], splitline[2]);
		OccurNum = 0;
		
		for (j = 0; j < t.length; j++) {
			eval("myRE = /" + t[j] + "/gi");
			OccurArray = refineAllString.match(myRE);
			if (OccurArray != null) {
				OccurNum = OccurNum + OccurArray.length;
			} else {
				allConfirmation = false;
			}
			
		}
		
		if (allConfirmation) {
			//Store results in MatchedResults, adding number of occurances on page, and splitting title out of brief description in Profiles
			TitleSep = splitline[1].indexOf("¤");	//Sep is actually "¤ "
			MatchedResults[indexer] = (0-OccurNum) + "|" + splitline[0] + "|" + splitline[1].substring(0, TitleSep) + "|" + splitline[1].substring(TitleSep+2) + "|" + splitline[2] + "|" + splitline[3];
			indexer++;
			}
		}
	if (MatchedResults.length == 0) {
		setTimeout("noMatch('"+text+"')",20); 	//write banner text. setTimeout only takes a literal string as the call to the function
		return;
	} else {
		SearchText = text;
		SortResults();
		formatResults(1);
	}
}



//If user wants exact phrase
function requirePhrase(t, text) {
	for (i = 0; i < profiles.length; i++) {
		var allConfirmation = true;
		//strip url out of search string
		var refineAllString = "";
		var splitline = profiles[i].split("|");
		//refineAllString: capitalised content for current page which gets searched
		refineAllString = mergeCaps(splitline[1], splitline[2]);
		var allElement = t.toUpperCase();
		var OccurNum = 0;
		
		eval("myRE = /" + t + "/gi");
		OccurArray = refineAllString.match(myRE);
		if (OccurArray != null) {
			OccurNum = OccurNum + OccurArray.length;
			//Store results in MatchedResults, adding number of occurances on page, and splitting title out of brief description in Profiles
			TitleSep = splitline[1].indexOf("¤");	//Sep is actually "¤ "
			MatchedResults[indexer] = (0-OccurNum) + "|" + splitline[0] + "|" + splitline[1].substring(0, TitleSep) + "|" + splitline[1].substring(TitleSep+2) + "|" + splitline[2] + "|" + splitline[3];
			indexer++;
		}

	}

	if (MatchedResults.length == 0) {
		setTimeout("noMatch('"+text+"')",20); 	//write banner text. setTimeout only takes a literal string as the call to the function
		return;
	}
	else { 
		SearchText = text;
		SortResults();
		formatResults(1); 
	}
}

function SortResults() {
//sorts MatchedResults based on the module order, and the filename
//the original order is maintained because all earlier code relies on this

     //reorder each matched result so sort can be done on module order and filename
     for (i = 0; i < MatchedResults.length; i++) {
          CurrentMatch = MatchedResults[i].split("|");
		  //search for ModuleIndex in the module title (not course title)
		  ModuleIndex=-1;
		  for (l = 0; l <= maxLectures; l++) {
			  CurrentLecture = CurrentMatch[1].substring(CurrentMatch[1].indexOf(": ") + 2);
//			  if (CurrentLecture.toUpperCase().search(Lectures [l] [0].toUpperCase()) >= 0) {
				if (CurrentLecture.toUpperCase() == Lectures [l][0].toUpperCase() ) {
			    	ModuleIndex=l;
			  	break;
			  }
		  }
		  var AlphaModuleIndex="";
		  if (ModuleIndex<10) AlphaModuleIndex="0" + ModuleIndex;
		  else AlphaModuleIndex = ModuleIndex;
	 	  MatchedResults[i] = AlphaModuleIndex + "|" + CurrentMatch[5] + "|" + CurrentMatch[0] + "|" + CurrentMatch[1] + "|" + CurrentMatch[2] + "|" + CurrentMatch[3] + "|" + CurrentMatch[4];
     }
	 MatchedResults.sort();
	 //reorder each string in MatchedResults back again
	 for (i = 0; i < MatchedResults.length; i++) {
	      CurrentMatch = MatchedResults[i].split("|"); 
		  MatchedResults[i] = CurrentMatch[2] +  "|" + CurrentMatch[3] +  "|" + CurrentMatch[4] +  "|" + CurrentMatch[5] +  "|" + CurrentMatch[6] +  "|" + CurrentMatch[1];
	 }
}

//*************************************************************
// Format no-results page
//*************************************************************
function noMatch(text) {								// Dyanmic HTML page with no results
var phrase="";
var NoWords=1;
var BannerText="";
	
	NoWords=(text.split(" ")).length;
	//Set the presentation text depending on the search criteria and the number of words searched for
	if (NoWords == 1) { phrase = "the text: ";}
	else {
		if (srcCrit == "any") { phrase = "any of the words: "; }
		if (srcCrit == "all") { phrase = "all of the words: "; }
		if (srcCrit == "phrase") { phrase = "the phrase: "; }
 	}		
    BannerText = '<h1 class="ToolsHeader">Search Results</h1><h1 class="ToolsHeader2">There were no matches found for ' + phrase + '<span class="SearchResult"> ' + text + '</span><br />&nbsp</h1>';
	MM_setTextOfLayer('BannerTitleLayer',parent.SearchResultsHeaderFrame.document,BannerText);
	return true;
	}
	
function MM_findObj(n, d) { //v4.0
  var p,i,x;  
  if(!d) 
  	d=document; 
  if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; 
	n=n.substring(0,p);
  }
  if(!(x=d[n])&&d.all) 
  	x=d.all[n]; 
  for (i=0;!x&&i<d.forms.length;i++) 
  	x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) 
  	x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) 
  	x=d.getElementById(n); 
  return x;
}

function MM_setTextOfLayer(objName,doc,newText) { //v3.0 generated by Dreamweaver
var	browserVersion = parseInt(navigator.appVersion);
		
	if ((obj=MM_findObj(objName, doc))!=null) with (obj)
		if ((navigator.appName.indexOf('Netscape')>-1) && (browserVersion == 4)) {
			document.write(unescape(newText)); 
			document.close();
		}
    	else innerHTML = unescape(newText);
}


function SearchResultPhrase (text){
var phrase="";
var NoWords=1;
	
	NoWords=(text.split(" ")).length;
	//Set the presentation text depending on the search criteria and the number of words searched for
	if (NoWords == 1) { phrase = "The text <span class='SearchResult'>" + text + '</span> was found in '; return phrase;}
	else {
		if (srcCrit == "any") { phrase = "Any of the words <span class='SearchResult'>" + text + '</span> were found in '; return phrase; }
		if (srcCrit == "all") { phrase = "All of the words <span class='SearchResult'>" + text + '</span> were found in '; return phrase; }
		if (srcCrit == "phrase") { phrase = "The phrase <span class='SearchResult'>" + text + '</span> was found in '; return phrase; }
 	}		
}

function WriteBanner (SearchText, thisPg, endPg, pgRange) {
//writes the text on the HeaderFrame
HeaderText="";

	HeaderText = '<h1 class="ToolsHeader">Search Results</h1><h1 class="ToolsHeader2">' + SearchResultPhrase(SearchText) + '<span class="SearchResult">' + MatchedResults.length + '</span> pages. ';
	if (MatchedResults.length > maxPages) {
	//if more pages found than can fit on one results page
		pgNum = parseInt(MatchedResults.length/maxPages);
		HeaderText += 'Matches ' + thisPg + ' - ' + endPg + ':</h1>';
		if (MatchedResults.length/maxPages > pgNum) pgNum++;
		pgLinks = "<h1 class='ToolsHeader2'>Go to page: ";
		for (i=0; i < pgNum; i ++) {
			if  (parseInt(i + 1) != pgRange) {
				//the number is not the current page => create link to it			
				locationStr = (parent.document.location.href.indexOf("&range=") > -1)? changeParam("range", parseInt(i + 1)):parent.document.location.href + "&range=" + parseInt(i + 1);
				//pgLinks += '<a class="GlossaryIndex" href=\'javascript:parent.ReLoadSearchResults(\"' + locationStr + '\")\'>' + (i + 1) + '</a> ';
				pgLinks += '<a class="GlossaryIndex" href=\'#\' onMouseUp="javascript:parent.formatResults(' + (i + 1) + ')">' + (i + 1) + '</a> ';				
		
			}
			else {
				//the current page - show it greyed out
				pgLinks += "<strong><span class='GlossaryIndex'>" + (i + 1) + "</span></strong> "
			}	
		}
		HeaderText += pgLinks + "</h1>";
	} 
	else {HeaderText += "</h1>"};
	MM_setTextOfLayer('BannerTitleLayer',SearchResultsHeaderFrame.document,HeaderText);
}

function MM_openBrWindow(theURL,winName,features) { //v2.0
   NewWindow = window.open(theURL,winName,features);
   return NewWindow;
  }
 
function OpenWindowCentralToScreen(page,name,Width,Height,Scroll){
//opens a new window positioned centrally in the lecture window (the parent).
var top = 0, left = 0;// default values

   top = (screen.availHeight - Height)/2;
   left =(screen.availWidth - Width)/2;

   NewWindow =  MM_openBrWindow(page,name,'scrollbars='+Scroll+',width='+Width+',height='+Height+',top='+top+',left='+left+',screenX='+left+',screenY='+top)
   return NewWindow;
}

function WriteToDetailsWindow() {
//Write the content to the Details window. Called after it's opened

	DetailsWindow.document.open();
	DetailsWindow.document.write(newContent);
	DetailsWindow.document.close();
}

function OpenDetailsWindow(Result, srcCrit, SearchText) {
//opens a blank window and writes the details of the selected search content to it
	
	//check to close a previously open DetailsWindow
	if (typeof(DetailsWindow)!="undefined"){
		if(!DetailsWindow.closed) {
			DetailsWindow.close();
		}
	}
	DetailsWindow = OpenWindowCentralToScreen("", "Details", 550,400, "yes");
	if (DetailsWindow != null) {
	 	CurrentMatch = MatchedResults[Result].split("|");
		//display search text in red
		wrdArray = (srcCrit != "phrase")? SearchText.split(" "):new Array(SearchText);
		CurrentMatch[2] = HighlightSearchText(CurrentMatch[2], wrdArray);
		CurrentMatch[3] = HighlightSearchText(CurrentMatch[3], wrdArray);
		CurrentMatch[4] = HighlightSearchText(CurrentMatch[4], wrdArray); 
		// force small delay for IE to catch up Couldn't get this to work passing any parameters to WriteToDetailsWindow
		//newContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html lang="en"><HEAD><TITLE>Full Search Details</TITLE></HEAD><link rel="stylesheet" href="../Content.css" type="text/css"><BODY><dl><dt>' + Title + '</dt><dd>' + BriefDesc.substring(0, BriefDesc.indexOf("...")) + RestContent + '</dd></dl></BODY></HTML>'	
		//setTimeout("WriteToDetailsWindow()", 50);
		DetailsWindow.document.open();
		DetailsWindow.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html lang="en"><HEAD><TITLE>Full Search Details</TITLE></HEAD><link rel="stylesheet" href="../Content.css" type="text/css"><BODY>');
		//write title, brief desc without terminating chars and rest of content
		DetailsWindow.document.write('<dl><dt>' + CurrentMatch [2] + '</dt><dd>' + CurrentMatch [3].substring(0, CurrentMatch [3].indexOf("...")) + CurrentMatch [4] + '</dd></dl>');  
		DetailsWindow.document.write('</BODY></HTML>');
		DetailsWindow.document.close();				
	}
}

function QuoteSafe (text) {
//takes the string in text and prefixes every single or double quote with a forward slash
var Safetext="";
var myRegExp1 = new RegExp("\'","g");
var myRegExp2 = new RegExp('\"',"g");

	Safetext = text.replace (myRegExp1, "\\'");
	Safetext = Safetext.replace (myRegExp2, '\\"');
	return Safetext;
}

function HighlightSearchText (Content, wrdArray){
//Loops through Content for occurences of search text (in wrdArray), and sets the font to display them in red

	for (j=0; j<wrdArray.length; j++) {
		eval("myRE1 = /" + wrdArray[j] + "/gi");
		regArr = null;
		regArr = Content.match(myRE1);
		if (regArr != null) {
			//look for uniqueness in regArr (its length gives no. matches in content)
			//beenThere stores the number of different version of the search text (capitals etc.)
			beenThere = new Array();
			for (k=0; k<regArr.length; k++) {
				beenhere = 0; 
				for (l=0; l<beenThere.length; l++) {
					if (beenThere[l] == regArr[k]) {
						beenhere = 1;
						//break;
					}
							
				}
				if (beenhere == 0) {
					beenThere[beenThere.length] = regArr[k];
					eval("myRE2 = /"+regArr[k]+"/g");
					Content = Content.replace(myRE2, "<\|>" + regArr[k] + "<\/\|>");
				}
			}
		}
	}
	myRE3 = /\<\|\>/g;
	myRE4 = /\<\/\|\>/g;
	//highlight search words in red for both brief description and rest content
	Content = Content.replace(myRE3, "<span class=\"HighlightSearchText\">");
	Content = Content.replace(myRE4, "</span>");
	return Content;
}

//*************************************************************
// Format successfull search results page
//*************************************************************
function formatResults(pgRange) {
//MatchedResults contains the list of result pages each in the format of:
//no. of times match occurs|module title|Page title|Brief desc|remaining content|file path and name
//SearchText is the search text.
//pgRange is the current page number that is to be formated
var LastLectureDisplayed="";	//the name of the lecture that the previous result page was in
var CurrentDisplayLecture="";	//the name of the lecture for the current result page

	//pgRange = (getQueryString("range") != "")? parseInt(getQueryString("range")):1;
	thisPg = 1;
	endPg = MatchedResults.length;
	if (MatchedResults.length > maxPages) {
	//if more pages found than can fit on one results page
		thisPg = (maxPages * pgRange) - (maxPages - 1);
		endPg = (parseInt(thisPg + (maxPages - 1)) < MatchedResults.length)? parseInt(thisPg + (maxPages - 1)):MatchedResults.length;
	}
	//Write the summary of the results to the HeaderFrame (intro a little delay for fast machinces!)
	setTimeout("WriteBanner('" + SearchText + "','" + thisPg + "','" + endPg + "','" + pgRange + "')",20); //setTimeout only takes a literal string as the call to the function
	wrdArray = (srcCrit != "phrase")? SearchText.split(" "):new Array(SearchText);
	SearchResultItemsFrame.document.open();
	SearchResultItemsFrame.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html lang="en"><HEAD><link rel="stylesheet" href="../Content.css" type="text/css"></HEAD><BODY>');
	for (i = (thisPg - 1); i < endPg; i++) {
		CurrentMatch = MatchedResults[i].split("|"); 			// Print each profile result as a unit of a definition list
		//CurrentMatch[0]=no. words matched, CurrentMatch[1]=module title, CurrentMatch[2]=title, CurrentMatch[3]=brief desc, CurrentMatch[4]=remaining content, CurrentMatch[5]=file path
		//Show search text in red
		CurrentMatch[3] = HighlightSearchText(CurrentMatch[3], wrdArray);
		CurrentMatch[4] = HighlightSearchText(CurrentMatch[4], wrdArray);

		//search for ModuleIndex in the module title (not course title)
		ModuleIndex=-1;
		for (l = 0; l <= maxLectures; l++) {
			CurrentLecture = CurrentMatch[1].substring(CurrentMatch[1].indexOf(": ") + 2);
			if (CurrentLecture.toUpperCase().search(Lectures [l] [0].toUpperCase()) >= 0) {
				ModuleIndex=l;
				break;
			}
		}
		if (ModuleIndex!=-1) {		
		//lecture identified		
			//write page title with a link to the file path and name
			CurrentDisplayLecture = CurrentMatch[1].substring(CurrentMatch[1].indexOf(": ") + 2);
			if (CurrentDisplayLecture != LastLectureDisplayed) {
				if (i == (thisPg - 1)) {
				//first match written to page (i.e. the top)
					SearchResultItemsFrame.document.writeln("<p class='ResourceHeader'><a  name=\"top_of_page\">" + CurrentDisplayLecture + "</a></p><dl>");
				}
				else {SearchResultItemsFrame.document.writeln("</dl><p class='ResourceHeader'>" + CurrentDisplayLecture + "</p><dl>");}
				LastLectureDisplayed = CurrentDisplayLecture;
			}
			//write lecture name with link to load page in course. Note, pages shown as popup only are not included in the siteIndex (i.e. they are excluded from the search criteria)
			SearchResultItemsFrame.document.writeln("<dt><a class='SearchLink' href=\"javascript:parent.LoadSearchPage('../LectureWindow.htm','" + CurrentMatch[5].substring(3) + "'," + ModuleIndex + ")\"><strong>" + CurrentMatch[2] + "</strong></a><\dt>"); //CurrentMatch[5] starts ../
			//write the brief description
			if (CurrentMatch[3] != "") {
				//there is some searchable text on the page
				SearchResultItemsFrame.document.writeln("<dd>" + CurrentMatch[3] + " <a class='DetailsLink' href=\"javascript:parent.OpenDetailsWindow(" + i + ",'" + srcCrit + "','" + SearchText + "')\"> more</a></dd><br /><br />");
			}
			else {
				//there is no searchable text on the page - i.e. just a diagram
				SearchResultItemsFrame.document.writeln("<dd> </dd><br /><br />");
			}
		}
		else {
			//module not found - do nothing.
			//SearchResultItemsFrame.document.writeln(CurrentMatch[1]); //debug			
		}		
	}//for
	// Write table and finish the HTML document
	SearchResultItemsFrame.document.writeln("</dl></BODY></HTML>");
	//SearchResultItemsFrame.document.writeln("</dl><table width='100%'><tr><td width='50%'>&nbsp;</td><td width='50%' align='right'><a href ='#top_of_page'><img style='cursor:hand' src='../Images/Top.gif' name='Top' border='0' onMouseOut='parent.MM_swapImgRestore()' onMouseOver=\"parent.MM_swapImage('Top','','../Images/TopHi.gif',1)\"></a></td></tr></table></BODY></HTML>");
	SearchResultItemsFrame.document.close();
}
	
